package com.ccb.sc.login.controller;

import com.auth0.jwt.interfaces.Claim;
import com.ccb.sc.auth.JWTHelper;
import com.ccb.sc.auth.TokenUtil;
import com.ccb.sc.constant.AppConst;
import com.ccb.sc.common.service.ISmsService;
import com.ccb.sc.login.service.IAppTokenService;
import com.ccb.sc.member.convert.AppMemberConvert;
import com.ccb.sc.member.service.AppMemberService;
import com.ccb.sc.member.vo.AppMemberVo;
//psl import com.ccb.sc.common.bind.exception.BizException;
import com.ccb.sc.common.bind.response.ResBody;
import com.ccb.sc.common.code.BizCodeFace;
import com.ccb.sc.common.code.ErrorCode;
import com.ccb.sc.common.constant.CommonRedisKey;
import com.ccb.sc.common.constant.RegexPatterns;
import com.ccb.sc.common.modules.member.entity.Member;
import com.ccb.sc.common.modules.member.enums.MemberStatus;
import com.ccb.sc.common.util.PasswordUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @author ken
 * @version 1.0
 * @date 2020-09-15
 */
@RestController
@RequestMapping("/app")
@Api(value = "账号密码手机号登录", tags = "账号密码手机号登录")
@Slf4j
public class AppLoginController {

    private IAppTokenService tokenService;
    private AppMemberService memberService;
    private ISmsService smsService;

    @PostMapping("/username/login")
    @ApiOperation(value = "用户名密码登录", response = AppMemberVo.class)
    public ResBody<?> loginByUsername(@ApiParam(value = "用户名", example = "17620370423") @RequestParam String username,
                                      @ApiParam(value = "密码", example = "123456")@RequestParam String password,
                                      @ApiIgnore HttpServletRequest request,
                                      @ApiIgnore HttpServletResponse response) {
        if (!StringUtils.hasText(username) || !StringUtils.hasText(password)) {
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.DATE_NULL).message("用户名或密码不能为空"));
        }
        Member member = this.memberService.findByPhone(username);
        if (member == null) {
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.ACCOUNT_NO_EXISTIS));
        }

        String encryptPassword = PasswordUtil.encodePassword(password, member.getSalt());
        if (!encryptPassword.equals(member.getPassword())) {
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.AUTH_FAIL).message("账号或密码错误"));
        }
        if (member.getStatus() == MemberStatus.DISABLED) {
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.ACCOUNT_LOCKED));
        }
        AppMemberVo vo = AppMemberConvert.INSTANCE.entityToVo(member);
        String token = TokenUtil.generateToken(member.getId(), request.getSession().getId());
        vo.setToken(token);
        //setHeader(response, member, null);
        response.addHeader(AppConst.TOKEN_HEAD_NAME, token);
        return ResBody.success(vo);
    }

    @PostMapping("/phone/login")
    @ApiOperation(value = "短信验证码登录", response = AppMemberVo.class)
    public ResBody<?> loginByPhone(@RequestParam String phone, @RequestParam String smsCode,
                                   @ApiIgnore HttpServletResponse response) {
        Assert.isTrue(phone.matches(RegexPatterns.MOBILE_PHONE_NUMBER_PATTERN), "请输入正确的手机号格式");
        boolean result = this.smsService.checkCode(phone, smsCode, String.format(CommonRedisKey.LOGIN_CODE, phone));
        if (!result) {
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.AUTH_FAIL).message("验证码错误"));
        }
        Member member = this.memberService.findByPhone(phone);
        if (member == null) {
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.ACCOUNT_NO_EXISTIS));
        }
        if (member.getStatus() == MemberStatus.DISABLED) {
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.ACCOUNT_LOCKED));
        }

        AppMemberVo vo = AppMemberConvert.INSTANCE.entityToVo(member);
        String token = TokenUtil.generateToken(member.getId(), phone);
        vo.setToken(token);
        response.addHeader(AppConst.TOKEN_HEAD_NAME, token);
        return ResBody.success(vo);
    }


    @PostMapping("/logout")
    @ApiOperation("退出")
    public ResBody<?> logout(HttpServletRequest request) {
        String tokenStr = request.getHeader(AppConst.TOKEN_HEAD_NAME);
        if (StringUtils.hasText(tokenStr)) {
            Map<String, Claim> claims = JWTHelper.unSign(tokenStr);
            if (claims != null && claims.containsKey(AppConst.MEMBER_SESSION_ATTR_KEY)) {
                String key = claims.get(AppConst.MEMBER_SESSION_ATTR_KEY).asString();
                this.tokenService.deleteToken(key);
            }
        }
        return ResBody.success().message("退出成功");
    }

    @Autowired
    public void setTokenService(IAppTokenService tokenService) {
        this.tokenService = tokenService;
    }

    @Autowired
    public void setMemberService(AppMemberService memberService) {
        this.memberService = memberService;
    }

    @Autowired
    public void setSmsService(ISmsService smsService) {
        this.smsService = smsService;
    }

}
